const https = require("https");
const express = require("express");
const { Server } = require("socket.io");
const fs = require("fs");
const path = require("path");

// global clients map
const client_map = {};

// create express engine
const app = express();

// http request handler
app.get("/onlineUsers", (req, res) => {
  res.writeHead(200, {
    "Content-type": "application/json",
  });
  res.end(JSON.stringify(Object.keys(client_map)));
});
app.post("/send", (data) => {
  console.log(data);
});

// create https server
const option = {
  key: fs.readFileSync(path.resolve("./cert/server.key")),
  cert: fs.readFileSync(path.resolve("./cert/server.crt")),
};
const server = https.createServer(option, app);

// attach socket.io to https server
const io = new Server(server);

// fixed room name
const room = "best";

// socket.io handler
io.on("connection", (socket) => {
  // handle user join event
  socket.on("join", (id) => {
    socket.join(room);
    client_map[id] = socket;
    socket.emit("joined", `${id} is joined`);

    syncOnlineUsers();
  });

  // handle user leave event
  socket.on("leave", (id) => {
    socket.leave(room);
    delete client_map[id];
    socket.emit("leaved", `${id} is leaved`);

    syncOnlineUsers();
  });

  // handle user invite event
  socket.on(
    "invite",
    ({
      inviter, // 邀请者
      participants, // 被邀请者列表
      title, // 会议主题
    }) => {
      participants.forEach((id) => {
        if (client_map[id]) {
          client_map[id].emit("invited", { inviter, title });
        }
      });
    }
  );

  // handle socket disconnect event
  socket.on("disconnecting", (reason) => {
    socket.leave(room);
    delete client_map[id];
    syncOnlineUsers();
    console.log(`client disconnected: ${reason}`);
  });
});

// broadcast online users to room clients
function syncOnlineUsers() {
  const onlineUsers = Object.keys(client_map);
  io.of("/").in(room).emit("online", onlineUsers);
}

// server begin to listen
server.listen(8443, "0.0.0.0");
